package fast.mvc;

import indzcraft.loader.Enchant;
import indzcraft.loader.EnchantDB;
import indzcraft.loader.Gem;
import indzcraft.loader.GemDB;
import indzcraft.loader.Item;
import indzcraft.loader.ItemEquipped;
import indzcraft.loader.Reforge;
import indzcraft.loader.ReforgeDB;
import indzcraft.loader.Slot;
import indzcraft.loader.SocketBonus;
import indzcraft.loader.Spec;
import indzcraft.ranking.EP;
import indzcraft.ranking.ItemCompare;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.ProgressMonitor;
import javax.swing.SwingWorker;

//import net.wsnetwork.reforger.Item;
import net.wsnetwork.reforger.Reforger;
import net.wsnetwork.reforger.ReforgingOption;
import net.wsnetwork.reforger.Stat;

public class Controller {

    private View view;
    private LoadProfileView loadProfileView;
    private Model model;

    public Controller(){
        this.model = new Model();
        this.view = new View();

        addListener();
        view.getIgnoreExp().setSelected(model.getSettings().isIgnoreExp());
        
        model.getEquipment().addPropertyChangeListener( new EquipmentListener() );
        
        showItemsInView();
    }
    
    public void showView(){
        this.view.setVisible(true);
    }

    private void addListener(){
        this.view.setCalcListener(new CalcListener());
        this.view.setLoadListener(new LoadListener());
        this.view.setSaveListener(new SaveListener());
        this.view.setLoadProfileListener(new LoadProfileListener());
        this.view.setAutoReforgeListener(new AutoReforgeListener());
        this.view.setAutoGemListener(new AutoGemListener());
        for(ItemSlotView isv : this.view.getItemMap().values()){
        	isv.setItemListener(new ItemListener());
        	isv.setEnchantListener(new EnchantListener());
        	isv.setGemListener(new GemListener());
        	isv.setReforgeListener(new ReforgeListener());
        }
        this.view.setSettingsListener(new SettingsListener());
        this.view.setChangeSpecListener(new ChangeSpecListener());
        this.view.setAltSpecListener(new AltSpecListener());
        this.view.setPlayerListener(new PlayerListener());
    }
    
    private void showItemsInView(){
    	for( Slot slot : model.getEquipment().equipment.keySet()){
    		ItemEquipped ie = model.getEquipment().get(slot);
    		ItemSlotView isv = view.getItemMap().get(slot);
    		
    		if(ie.getItem() != null){
	        	String enchant = "N";
	        	if(model.getEquipment().get(slot).getEnchant() != null)
	        		enchant = ie.getEnchant().getName();
	
	        	isv.setIcon(ie.getItem().getIcon());
	        	if(slot.isEnchantable())
	        		isv.setEnchant(enchant);
	        	
	        	String[] slotColors = ie.getItem().getGemSlot();
	        	Gem[] gems = ie.gem;
	        	for(int j = 0;j < gems.length; j++){
	        		if(gems[j] != null)
	        			isv.setGem(j, gems[j].getIcon());
	        		else
	        			isv.setGemSlot(j, slotColors[j]);
	        	}
	        	Reforge r = ie.getReforge();
	        	isv.setReforge(r.getFrom(), r.getTo());
	        	isv.setInfo(ie.getItem().getItemLevel(), ie.getItem().getSet());
	        	isv.setTooltip(ie.getItem().getTooltip());
    		}else{
    			isv.setIcon("inv_misc_questionmark");
    		}
        }
    }

    class CalcListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            System.out.println("calc");
            model.calcFast();
            view.setDPS(String.valueOf(Math.round(model.getDPS())));
            view.setStats(model.getEP(),model.getStats());
        }
    }
    
    class LoadListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            System.out.println("load");
            model.loadCharacter(view.getRegion(),view.getServer(),view.getPlayer());
            model.getEquipment().addPropertyChangeListener( new EquipmentListener() );
            view.addLog("Spec: " + model.getLoader().getBase().getSpec().name());
            view.setActiveSpec(model.getLoader().getBase().getSpec().name());
            
            showItemsInView();
            
            model.calcFast();
            view.setDPS(String.valueOf(Math.round(model.getDPS())));
            view.setStats(model.getEP(),model.getStats());
        }
    }
    
    class SaveListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            System.out.println("save");
            model.saveCharacter();
        }
    }
    
    class LoadProfileListener implements ActionListener {
    	public void actionPerformed(ActionEvent e) {
    		System.out.println("load profile");
    		loadProfileView = new LoadProfileView(model.getLoader().getProfiles());
    		loadProfileView.setLoadListener(new LoadProfile2Listener());
    		loadProfileView.setVisible(true);
    	}
    }
    
    class LoadProfile2Listener implements ActionListener {
    	public void actionPerformed(ActionEvent e) {
    		String selected = loadProfileView.getSelectedProfile();
    		System.out.println(selected);
    	}
    }
    
    class ItemListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
        	JButton isv = (JButton) e.getSource();
        	ItemSlotView v = (ItemSlotView) isv.getParent();
            Slot s = v.getSlot();
            view.newItemPanel(s);
            
            ArrayList<Item> itemsForSlot = model.getDatabase().findAllWithInventorySlot(s);
            ArrayList<Item> items = new ArrayList<Item>();
            boolean isPlayerEng = model.getLoader().getBase().getProfessions().contains("Engineering");
            for(Item ie : itemsForSlot){
            	if(ie.getReqSkill() == 202 && !isPlayerEng)
            		continue;
            	items.add(ie);
            }
            Item curItem = null;
            if(model.getEquipment().get(s) != null)
            	curItem = model.getEquipment().get(s).getItem();
    		ItemCompare<Item> ic = new ItemCompare<Item>(model,curItem,items,s);
    		ArrayList<EP<Item>> itemep = ic.getComperator();
    		Iterator<EP<Item>> it = itemep.iterator();
    		
            view.getItemPanel().showItems(it,curItem);
            
            view.showItemPanel(s);
            //int pos = view.getItemPanel().getSelectedPosition();
            //view.getSidePanel().getVerticalScrollBar().setValue(pos);
            
            HashMap<JButton,Item> items2 = view.getItemPanel().getItems();
            for(JButton b : items2.keySet()){
            	view.getItemPanel().addItemChangeListener(b,new ItemChangeListener(s,items2.get(b)));
            }
        }
    }
    
    class EnchantListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			JButton isv = (JButton) e.getSource();
        	ItemSlotView v = (ItemSlotView) isv.getParent();
            Slot s = v.getSlot();
            //System.out.println(s.getName());
            view.showEnchantPanel(s);
            
            String slotName = s.getName();
            if(slotName.endsWith("1") || slotName.endsWith("2")){
            	slotName = slotName.substring(0, slotName.length()-1);
            }else if(slotName.equals("mainHand") || slotName.equals("offHand")){
            	slotName = "weapon";
            }
            // load enchants
            Enchant curEnchant = model.getEquipment().get(s).getEnchant();
            Item item = model.getLoader().getEquipment().get(s).getItem();
    		EnchantDB enchantDB = model.getLoader().getEnchantDB();
    		ArrayList<Enchant> items = new ArrayList<Enchant>();
    		boolean isPlayerEnchanter = model.getLoader().getBase().getProfessions().contains("Enchanting");
    		boolean isPlayerLeatherworker = model.getLoader().getBase().getProfessions().contains("Leatherworking");
    		boolean isPlayerInscripter = model.getLoader().getBase().getProfessions().contains("Inscription");
    		boolean isPlayerTailor = model.getLoader().getBase().getProfessions().contains("Tailoring");
    		for ( Enchant elem : enchantDB.getDB().values() ){
    			// enchanter only enchants
    			if(elem.isEnchanterOnly() && !isPlayerEnchanter){
    				continue;
    			}
    			if(elem.isLeatherworkerOnly() && !isPlayerLeatherworker){
    				continue;
    			}
    			if(elem.isInscripterOnly() && !isPlayerInscripter){
    				continue;
    			}
    			if(elem.isTailorOnly() && !isPlayerTailor){
    				continue;
    			}
    			if(elem.getExp() > 0 && model.getSettings().isIgnoreExp()){
    				if(curEnchant != elem)
    					continue;
    			}
    			if(elem.getSlotName().equals(slotName))
    				items.add(elem);

    		}
    		items.add(null);
    		ItemCompare<Enchant> ic = new ItemCompare<Enchant>(model,item,items,s);
    		ArrayList<EP<Enchant>> itemep = ic.getComperator();
    		Iterator<EP<Enchant>> it = itemep.iterator();
            
            view.getEnchantPanel().showItems(it,curEnchant);
            HashMap<JButton,Enchant> items2 = view.getEnchantPanel().getItems();
            for(JButton b : items2.keySet()){
            	view.getEnchantPanel().addEnchantChangeListener(b,new EnchantChangeListener(s,items2.get(b)));
            }
        }
    }
    
    class ReforgeListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			JButton isv = (JButton) e.getSource();
        	ItemSlotView v = (ItemSlotView) isv.getParent();     
            Slot s = v.getSlot();
            //System.out.println(s.getName());
            view.showReforgePanel(s);
            
            // load reforge
            Reforge curReforge = model.getEquipment().get(s).getReforge();
            Item item = model.getLoader().getEquipment().get(s).getItem();
            //String gemSlotColor = model.getLoader().getEquipment().get(s).getGemSlot()[gemSlot];
    		ReforgeDB reforgeDB = model.getLoader().getReforgeDB();
    		ArrayList<Reforge> items = new ArrayList<Reforge>();
    		for ( Reforge elem : reforgeDB.getDB().values() ){
    			if(model.hasItemStat(item,"white_hit") && elem.getFrom().equals("Hit Rating"))
    				items.add(elem);
    			else if(model.hasItemStat(item,"crit") && elem.getFrom().equals("Crit Rating"))
    				items.add(elem);
    			else if(model.hasItemStat(item,"haste") && elem.getFrom().equals("Haste Rating"))
    				items.add(elem);
    			else if(model.hasItemStat(item,"mastery") && elem.getFrom().equals("Mastery Rating"))
    				items.add(elem);
    			else if(model.hasItemStat(item,"exp") && elem.getFrom().equals("Expertise Rating"))
    				items.add(elem);
    			if(model.hasItemStat(item,"white_hit") && elem.getTo().equals("Hit Rating"))
    				items.remove(elem);
    			else if(model.hasItemStat(item,"crit") && elem.getTo().equals("Crit Rating"))
    				items.remove(elem);
    			else if(model.hasItemStat(item,"haste") && elem.getTo().equals("Haste Rating"))
    				items.remove(elem);
    			else if(model.hasItemStat(item,"mastery") && elem.getTo().equals("Mastery Rating"))
    				items.remove(elem);
    			else if(model.hasItemStat(item,"exp") && elem.getTo().equals("Expertise Rating"))
    				items.remove(elem);
    		}
    		ItemCompare<Reforge> ic = new ItemCompare<Reforge>(model,item,items,s);
    		ArrayList<EP<Reforge>> itemep = ic.getComperator();
    		Iterator<EP<Reforge>> it = itemep.iterator();
            
            view.getReforgePanel().showItems(it,curReforge);
            HashMap<JButton,Reforge> items2 = view.getReforgePanel().getItems();
            for(JButton b : items2.keySet()){
            	view.getReforgePanel().addReforgeChangeListener(b,new ReforgeChangeListener(s,items2.get(b)));
            }
        }
    }
    
    class GemListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
        	JButton isv = (JButton) e.getSource();
        	ItemSlotView v = (ItemSlotView) isv.getParent();
        	JButton[] gemButtons = v.getGems();
        	int gemSlot = -1;
        	for(int i = 0;i < gemButtons.length;i++){
        		if(gemButtons[i].equals(isv)){
        			gemSlot = i;
        			break;
        		}	
        	}
            Slot s = v.getSlot();
            //System.out.println(s.getName());
            view.showGemPanel(s,gemSlot);
            
            // load gems
            Gem curGem = model.getEquipment().get(s).getGem(gemSlot);
            Item item = model.getLoader().getEquipment().get(s).getItem();
            String gemSlotColor = item.getGemSlot()[gemSlot];
    		GemDB gemDB = model.getLoader().getGemDB();
    		ArrayList<Gem> items = new ArrayList<Gem>();
    		boolean isPlayerJC = model.getLoader().getBase().getProfessions().contains("Jewelcrafting");
    		boolean isPlayerEng = model.getLoader().getBase().getProfessions().contains("Engineering");
    		for ( Gem elem : gemDB.getDB().values() ){
    			// 755 jewelcrafting
    			if(elem.getReqSkill() == 755 && !isPlayerJC){
    				continue;
    			}
    			else if(elem.getReqSkill() == 202 && !isPlayerEng){
    				continue;
    			}
    			if(elem.getExp() > 0 && model.getSettings().isIgnoreExp()){
    				if(curGem != elem)
    					continue;
    			}
    			
    			if(gemSlotColor.equals("META") && elem.getType() == Gem.META)
    				items.add(elem);
    			else if(gemSlotColor.equals("COGWHEEL") && elem.getType() == Gem.COGWHEEL)
    				items.add(elem);
    			else if(gemSlotColor.equals("HYDRAULIC") && elem.getType() == Gem.HYDRAULIC)
    				items.add(elem);
    			else if(		(!gemSlotColor.equals("COGWHEEL") && elem.getType() != Gem.COGWHEEL) 
    						&& (!gemSlotColor.equals("META") && elem.getType() != Gem.META)
    						&& (!gemSlotColor.equals("HYDRAULIC") && elem.getType() != Gem.HYDRAULIC)
    					)
    				items.add(elem);
    		}
    		items.add(null);
    		ItemCompare<Gem> ic = new ItemCompare<Gem>(model,item,items,s);
    		ArrayList<EP<Gem>> itemep = ic.getComperator();
    		Iterator<EP<Gem>> it = itemep.iterator();
            
            view.getGemPanel().showItems(it,curGem);
            HashMap<JButton,Gem> items2 = view.getGemPanel().getItems();
            for(JButton b : items2.keySet()){
            	view.getGemPanel().addGemChangeListener(b,new GemChangeListener(s,view.getGemPanel().getGemSlot(),items2.get(b)));
            }
        }
    }
    
    class PlayerListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			List<String> glyphs = model.getLoader().getBase().getGlyphs();
            view.showPlayerPanel(model.getLoader().getBase().getRace(),model.getLoader().getBase().getProfessions().toArray(new String[2]),glyphs);
            view.getPlayerPanel().addRaceChangeListener(new RaceChangeListener());
            
            view.getPlayerPanel().addProfessionChangeListener(new ProfessionChangeListener());
            view.getPlayerPanel().addGlyphChangeListener(new GlyphChangeListener());
        }
    }
    
    class ItemChangeListener implements ActionListener {
    	private Slot slot;
    	private Item item;
    	
    	public ItemChangeListener(Slot s,Item item2){
    		slot = s;
    		item = item2;
    	}
		public void actionPerformed(ActionEvent e) {
			ItemEquipped ie = new ItemEquipped();
			if(slot == Slot.waist) {
				for(int i = 0; i < item.gemSlot.length; i++){
					if(item.gemSlot[i].equals("PRISMATIC"))
						break;
					else if(item.gemSlot[i].equals("")){
						item.gemSlot[i] = "PRISMATIC";
						break;
					}
				}
			}
			if(model.getLoader().getBase().getProfessions().contains("Blacksmithing") && (slot == Slot.wrist || slot == Slot.hands)) {
				for(int i = 0; i < item.gemSlot.length; i++){
					if(item.gemSlot[i].equals("PRISMATIC"))
						break;
					else if(item.gemSlot[i].equals("")){
						item.gemSlot[i] = "PRISMATIC";
						break;
					}
				}
			}else if(slot == Slot.wrist || slot == Slot.hands){
				for(int i = 0; i < item.gemSlot.length; i++){
					if(item.gemSlot[i].equals("PRISMATIC")){
						item.gemSlot[i] = "";
						break;
					}
				}
			}
			ie.setItem(item);
			for(int i = 0;i < item.gemSlot.length;i++){
				Gem gem = model.getBestGem(item.gemSlot[i]);
				ie.setGem(i, gem);
			}
			Enchant enchant = model.getBestEnchant(slot);
			ie.setEnchant(enchant);
			Reforge reforge = model.getBestReforge(item);
			ie.setReforge(reforge);
			model.getEquipment().put(slot, ie);
		}
    }
    
    class EnchantChangeListener implements ActionListener{
    	private Slot slot;
    	private Enchant enchant;
    	
    	public EnchantChangeListener(Slot s,Enchant e){
    		slot = s;
    		enchant = e;
    	}
		public void actionPerformed(ActionEvent e) {
			System.out.println("change enchant");
			model.getEquipment().setEnchant(slot, enchant);
			//.get(slot.getName()).setEnchant(enchant);
		}
    }
    
    class GemChangeListener implements ActionListener{
    	private Slot slot;
    	private int gemSlot;
    	private Gem gem;
    	
    	public GemChangeListener(Slot s,int gs,Gem g){
    		slot = s;
    		gemSlot = gs;
    		gem = g;
    	}
		public void actionPerformed(ActionEvent e) {
			System.out.println("change gem");
			model.getEquipment().setGem(slot, gemSlot, gem);
		}
    }
    
    class ReforgeChangeListener implements ActionListener{
    	private Slot slot;
    	private Reforge reforge;
    	
    	public ReforgeChangeListener(Slot s,Reforge r){
    		slot = s;
    		reforge = r;
    	}
		public void actionPerformed(ActionEvent e) {
			System.out.println("change reforge");
			model.getEquipment().setReforge(slot, reforge);
		}
    }
    
    class AutoReforgeTask extends SwingWorker<Void, Void> {
    	
    	Reforger ref = null;
        @Override
        public Void doInBackground() {
        	try{
        		ref = new Reforger();
        		setProgress(2);
        		ref.runReforging2((HashMap<String, Double>) model.getEP(),model.getEquipment(),model.getLoader().getBase().getSpec());
        		setProgress(100);
        	} catch (InterruptedException e1) {
				e1.printStackTrace();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
            return null;
        }
 
        @Override
        public void done() {
        	ReforgeDB reforgeDB = model.getLoader().getReforgeDB(); 
			List<ReforgingOption> results = ref.getResults();
			if(results != null){				
				for (ReforgingOption option : results) {
					Reforge re = new Reforge();
					for(int p = 0;p < Stat.possibleStats.length;p++){
						if(Stat.possibleStats[p].getIndex() == option.getFromStatIndex()){
							re.setFrom(Stat.possibleStats[p].getReforgeName());
						}else if(Stat.possibleStats[p].getIndex() == option.getToStatIndex()){
							re.setTo(Stat.possibleStats[p].getReforgeName());
						}
					}
					re = reforgeDB.getReforge(re);
					System.out.println(option.getItem().getSlotName());
					Reforge curReforge = model.getEquipment().get(Slot.valueOf(option.getItem().getSlotName())).getReforge();
					if(!curReforge.equals(re))
						view.addLog("Reforging " + option.getItem().getName() + " to -" + option.getDeltaValue() + " " + re.getFrom() + " / +" + option.getDeltaValue() + " " + re.getTo());
					model.getEquipment().setAutoReforge(Slot.valueOf(option.getItem().getSlotName()), re);
		        }
			}
			Set<net.wsnetwork.reforger.Item> notReforgedItems = ref.getNotReforgedItems();
			for(net.wsnetwork.reforger.Item item : notReforgedItems){
				model.getEquipment().setAutoReforge(Slot.valueOf(item.getSlotName()), null);
				view.addLog("Removed reforge from " + item.getName());
			}
			model.getEquipment().fireAutoReforgeComplete();
        }
    }
    
    class AutoReforgeListener implements ActionListener, PropertyChangeListener{
    	
    	ProgressMonitor progressMonitor;
    	AutoReforgeTask task;
    	
    	public void actionPerformed(ActionEvent e) {
    		
			progressMonitor = new ProgressMonitor(view,"Reforging","", 0, 100);
			progressMonitor.setProgress(0);
			task = new AutoReforgeTask();
	        task.addPropertyChangeListener(this);
	        task.execute();
	        view.getAutoReforgeButton().setEnabled(false);
    	}
    	
    	public void propertyChange(PropertyChangeEvent evt) {
            if ("progress" == evt.getPropertyName() ) {
                int progress = (Integer) evt.getNewValue();
                progressMonitor.setProgress(progress);
                String message =
                    String.format("Completed %d%%.\n", progress);
                progressMonitor.setNote(message);
                //taskOutput.append(message);
                if (progressMonitor.isCanceled() || task.isDone()) {
                    //Toolkit.getDefaultToolkit().beep();
                    if (progressMonitor.isCanceled()) {
                        task.cancel(true);
                        //taskOutput.append("Task canceled.\n");
                    } else {
                        //taskOutput.append("Task completed.\n");
                    }
                    view.getAutoReforgeButton().setEnabled(true);
                }
            }
     
        }
     
    }
    
    class AutoGemListener implements ActionListener {
    	public void actionPerformed(ActionEvent e) {
    		Gem bestMeta = model.getBestGem("META");
    		Gem bestRed = model.getBestGem("RED");
    		Gem bestYellow = model.getBestGem("YELLOW");
    		Gem bestBlue = model.getBestGem("BLUE");
    		Gem bestHydraulic = model.getBestGem("HYDRAULIC");
    		System.out.println(bestHydraulic.getName());
    		double bestMetaEP = model.calcGemEP(bestMeta);
    		double bestRedEP = model.calcGemEP(bestRed);
    		double bestYellowEP = model.calcGemEP(bestYellow);
    		double bestBlueEP = model.calcGemEP(bestBlue);
    		double bestHydraulicEP = model.calcGemEP(bestHydraulic);
    		
    		Gem bestGem = bestRed;
    		if(bestYellowEP > model.calcGemEP(bestGem))
    			bestGem = bestYellow;
    		if(bestBlueEP > model.calcGemEP(bestGem))
    			bestGem = bestBlue;
    		double bestGemEP = model.calcGemEP(bestGem);
    		    		
    		System.out.println("best ep: " + bestGem.getName() + " " + bestGemEP);
    		
    		for(Slot slot : model.getEquipment().equipment.keySet()){
    			System.out.println(slot);
    			
    			ItemEquipped ie = model.getEquipment().get(slot);
    			if(ie != null){
    				double gemMatchEP = 0.;
    				String[] gemSlot = ie.getItem().getGemSlot();
    				for(int i = 0;i < gemSlot.length;i++){
    					if(gemSlot[i].equals("RED")){
    						gemMatchEP += bestRedEP;
    					}else if(gemSlot[i].equals("YELLOW")){
    						gemMatchEP += bestYellowEP;
    					}else if(gemSlot[i].equals("BLUE")){
    						gemMatchEP += bestBlueEP;
    					}else if(gemSlot[i].equals("PRISMATIC")){
    						gemMatchEP += bestGemEP;
    					}else if(gemSlot[i].equals("HYDRAULIC")){
    						gemMatchEP += bestHydraulicEP;
    					}
    				}
        			double gemSocketEP = 0.;
        			if(ie.getItem().getSocketBonus() != null){
        				SocketBonus sb = ie.getItem().getSocketBonus();
        				gemSocketEP += model.getEP().get("agi")*sb.getAgi();
        				gemSocketEP += model.getEP().get("white_hit")*sb.getHit();
        				gemSocketEP += model.getEP().get("exp")*sb.getExp();
        				gemSocketEP += model.getEP().get("haste")*sb.getHaste();
        				gemSocketEP += model.getEP().get("mastery")*sb.getMastery();
        				gemSocketEP += model.getEP().get("crit")*sb.getCrit();
        			}
      
        			gemMatchEP += gemSocketEP;
        			
        			double gemOnlyBestEP = 0.;
        			//boolean gemOnlyBestMatch = true;
        			for(int i = 0;i < gemSlot.length;i++){
        				if(gemSlot[i].equals("META")){
        					//gemOnlyBestEP += bestMetaEP;
    					}
    					else if(!gemSlot[i].equals("")){
        					gemOnlyBestEP += bestGemEP;
        				}
        			}
        			if(gemOnlyBestEP > gemMatchEP){
        				for(int i = 0;i < gemSlot.length;i++){
        					if(gemSlot[i].equals("META")){
        						ie.setGem(i, bestMeta);
        					}else if(gemSlot[i].equals("HYDRAULIC")){
        						ie.setGem(i, bestHydraulic);
        					}
        					else if(!gemSlot[i].equals("")){
        						ie.setGem(i, bestGem);
        					}
        				}
        			} else {
        				for(int i = 0;i < gemSlot.length;i++){
        					if(gemSlot[i].equals("META")){
        						ie.setGem(i, bestMeta);
        					}
        					else if(gemSlot[i].equals("RED")){
        						ie.setGem(i, bestRed);
        					}
        					else if(gemSlot[i].equals("YELLOW")){
        						ie.setGem(i, bestYellow);
        					}
        					else if(gemSlot[i].equals("BLUE")){
        						ie.setGem(i, bestBlue);
        					}
        					else if(gemSlot[i].equals("PRISMATIC")){
        						ie.setGem(i, bestGem);
        					}
        					else if(gemSlot[i].equals("HYDRAULIC")){
        						ie.setGem(i, bestHydraulic);
        					}
        				}
        			}
    			}
    		}
    		model.getEquipment().fireAutoGemComplete();
    	}
    }
    
    class SettingsListener implements ActionListener {
    	public void actionPerformed(ActionEvent e) {
	    	if(e.getSource() == view.getIgnoreExp()){
	    		model.getSettings().setIgnoreExp(view.getIgnoreExp().isSelected());
	    	}
    	}
    }
    
    class ChangeSpecListener implements ActionListener {
    	public void actionPerformed(ActionEvent e) {
	    	Spec activeSpec = model.getLoader().getBase().getSpec();
	    	List<String> activeGlyphs = model.getLoader().getBase().getGlyphs();
	    	Spec inactiveSpec = model.getLoader().getBase().getOffSpec();
	    	List<String> inactiveGlyphs = model.getLoader().getBase().getOffGlyphs();
	    	model.getLoader().getBase().setSpec(inactiveSpec);
	    	model.getLoader().getBase().setGlyphs(inactiveGlyphs);
	    	model.getLoader().getBase().setOffSpec(activeSpec);
	    	model.getLoader().getBase().setOffGlyphs(activeGlyphs);
	    	
	    	view.setActiveSpec(inactiveSpec.name());
	    	
	    	model.calcFast();
            view.setDPS(String.valueOf(Math.round(model.getDPS())));
            view.setStats(model.getEP(),model.getStats());
            
            view.getSidePanel().setViewport(null);
    	}
    }
    
    class AltSpecListener implements ActionListener {
    	public void actionPerformed(ActionEvent e) {
	    	Spec activeSpec = model.getLoader().getBase().getSpec();
	    	Spec inactiveSpec = model.getLoader().getBase().getOffSpec();
	    	Spec newSpec;
	    	if(activeSpec != Spec.Assassination && inactiveSpec != Spec.Assassination)
	    		newSpec = Spec.Assassination;
	    	else if(activeSpec != Spec.Combat && inactiveSpec != Spec.Combat)
	    		newSpec = Spec.Combat;
	    	else
	    		newSpec = Spec.Subtlety;
	    	
	    	model.getLoader().getBase().setSpec(newSpec);
	    	view.setActiveSpec(newSpec.name());
	    	
	    	model.calcFast();
            view.setDPS(String.valueOf(Math.round(model.getDPS())));
            view.setStats(model.getEP(),model.getStats());
    	}
    }
    
    class RaceChangeListener implements ActionListener {
    	public void actionPerformed(ActionEvent e) {
			@SuppressWarnings("unchecked")
			JComboBox<String> raceList = (JComboBox<String>) e.getSource();
	    	String race = (String) raceList.getSelectedItem();
	    	model.getLoader().getBase().setRace(race);
	    	
	    	model.calcFast();
            view.setDPS(String.valueOf(Math.round(model.getDPS())));
            view.setStats(model.getEP(),model.getStats());
    	}
    }
    
    class ProfessionChangeListener implements ActionListener {
    	public void actionPerformed(ActionEvent e) {
	    	
    		model.getLoader().getBase().setProfessions(view.getPlayerPanel().getSelectedProfessions());
    		if(model.getLoader().getBase().getProfessions().contains("Blacksmithing")){
    			model.getEquipment().addExtraSocket(Slot.wrist);
    			model.getEquipment().addExtraSocket(Slot.hands);
    		}else{
    			model.getEquipment().removeExtraSocket(Slot.wrist);
    			model.getEquipment().removeExtraSocket(Slot.hands);
    		}
    		if(!model.getLoader().getBase().getProfessions().contains("Enchanting")){
    			model.getEquipment().get(Slot.finger1).setEnchant(null);
    			model.getEquipment().get(Slot.finger2).setEnchant(null);
    		}
    		model.getEquipment().fireProfessionChangeComplete();
    		
	    	model.calcFast();
            view.setDPS(String.valueOf(Math.round(model.getDPS())));
            view.setStats(model.getEP(),model.getStats());
    	}
    }
    
    class GlyphChangeListener implements ActionListener {
    	public void actionPerformed(ActionEvent e) {
    		JCheckBox glyph = (JCheckBox) e.getSource();
    		if(glyph.isSelected())
    			model.getLoader().getBase().addGlyph(glyph.getText());
    		else
    			model.getLoader().getBase().removeGlyph(glyph.getText());
    		
    		model.calcFast();
            view.setDPS(String.valueOf(Math.round(model.getDPS())));
            view.setStats(model.getEP(),model.getStats());
    	}
    }

	class EquipmentListener implements PropertyChangeListener {
		public void propertyChange(PropertyChangeEvent evt) {
			double oldDPS = model.getDPS();
			model.calcFast();
			view.setDPS(String.valueOf(Math.round(model.getDPS())));
			view.setStats(model.getEP(),model.getStats());
            showItemsInView();
            
			if(evt.getPropertyName().endsWith("enchant")){
				System.out.println("change: " + evt.getPropertyName());
				String[] arg = evt.getPropertyName().split("_");
				view.getItemMap().get(Slot.valueOf(arg[0])).getEnchant().doClick();
			}else if(evt.getPropertyName().endsWith("autogem")){
				System.out.println("change: " + evt.getPropertyName());
			}else if(evt.getPropertyName().endsWith("gem")){
				System.out.println("change: " + evt.getPropertyName());
				String[] arg = evt.getPropertyName().split("_");
				view.getItemMap().get(Slot.valueOf(arg[0])).getGems()[Integer.parseInt(arg[1])].doClick();
			}else if(evt.getPropertyName().endsWith("professionchange")){
				System.out.println("change: " + evt.getPropertyName());
			}else if(evt.getPropertyName().endsWith("autoreforge")){
				System.out.println("change: " + evt.getPropertyName());
			}else if(evt.getPropertyName().endsWith("reforge")){
				String[] arg = evt.getPropertyName().split("_");
				view.getItemMap().get(Slot.valueOf(arg[0])).getReforge().doClick();
			}else{
				view.getItemMap().get(Slot.valueOf(evt.getPropertyName())).getItem().doClick();
			}
			double diff = model.getDPS() - oldDPS;
			String output = "DPS: " + String.valueOf(Math.round(model.getDPS()));
			output += " (";
			if(diff >= 0)
				output += " +";
			output += String.valueOf(Math.round(diff)) + ")";
			View.addConsole(output);
		}
	}
}